#ifndef _CHECKPOINT_H_
#define _CHECKPOINT_H_

//#define DEBUG_INFO


#ifdef DEBUG_INFO
#define ckprintf kprintf
#else
#define ckprintf dummy
#endif

#define CHECKPOINT_VERSION  1

/* specially for i386 */
#define CKPT_ARCH_I386 0x1
#define CKPT_ARCH_ID CKPT_ARCH_I386

/* checkpoint user flags */
#define CHECKPOINT_SUBTREE	0x1  // checkpoint the process tree
#define CHECKPOINT_FILECLOSE 0x100

/* restart user flags */
#define RESTART_TASKSELF	0x1
#define RESTART_FROZEN		0x2
#define RESTART_GHOST		0x4
#define RESTART_KEEP_LSM	0x8
#define RESTART_CONN_RESET      0x10

/* misc user visible */
#define CHECKPOINT_FD_NONE	-1

/* ckpt_ctx: kflags */
#define CKPT_CTX_CHECKPOINT_BIT		0
#define CKPT_CTX_RESTART_BIT		1
#define CKPT_CTX_SUCCESS_BIT		2
#define CKPT_CTX_ERROR_BIT		3
#define CKPT_CTX_DROPPED_BIT		4

#define CKPT_CTX_CHECKPOINT	(1 << CKPT_CTX_CHECKPOINT_BIT)
#define CKPT_CTX_RESTART	(1 << CKPT_CTX_RESTART_BIT)
#define CKPT_CTX_SUCCESS	(1 << CKPT_CTX_SUCCESS_BIT)
#define CKPT_CTX_ERROR		(1 << CKPT_CTX_ERROR_BIT)
#define CKPT_CTX_DROPPED	(1 << CKPT_CTX_DROPPED_BIT)

#include <checkpoint_types.h>

/* sycall helpers */
extern int do_sys_checkpoint(pid_t pid, int fd, uint32_t flags, int logfd);
extern int do_sys_restart(pid_t pid, int fd, uint32_t flags, int logfd);

extern int do_checkpoint(struct ckpt_ctx *ctx, pid_t pid);
extern int do_restart(struct ckpt_ctx *ctx, pid_t pid, unsigned long flags);

// U11 : for current process ref
#define current pls_current

extern int walk_task_subtree(struct proc_struct *task,
			     int (*func)(struct proc_struct *, void *),
			     void *data);

// Image functions
void init_chunk_header(struct ckpt_chunk_header *chead, int type);
int write_chunk(struct ckpt_ctx *ctx, struct ckpt_chunk_header *chead, void* obj);
int write_bits(struct ckpt_ctx *ctx, uintptr_t base, uint32_t size);

void switchtopgdir(struct mm_struct *mm);

void dummy(char* p, ...);

#endif

